package com.scwatch.ext.service.impl;

import com.scwatch.common.orm.Limitable;
import com.scwatch.common.orm.RowSide;
import com.scwatch.common.orm.SearchFilter;
import com.scwatch.core.domain.Site;
import com.scwatch.core.listener.SiteDeleteListener;
import com.scwatch.core.service.SiteService;
import com.scwatch.core.support.DeleteException;
import com.scwatch.ext.domain.LiveBroadcast;
import com.scwatch.ext.domain.LiveBroadcastAddress;
import com.scwatch.ext.repository.LiveBroadcastDao;
import com.scwatch.ext.service.LiveBroadcastAddressService;
import com.scwatch.ext.service.LiveBroadcastService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Service
@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED)
public class LiveBroadcastServiceImpl implements LiveBroadcastService, SiteDeleteListener {
    public void preSiteDelete(Integer[] ids) {
        if (ArrayUtils.isNotEmpty(ids)) {
            if (dao.countBySiteId(Arrays.asList(ids)) > 0) {
                throw new DeleteException("LiveBroadcast.management");
            }
        }
    }


    public Page<LiveBroadcast> findAll(Integer siteId, Map<String, String[]> params, Pageable pageable) {
        return dao.findAll(spec(siteId, params), pageable);
    }


    public RowSide<LiveBroadcast> findSide(Integer siteId, Map<String, String[]> params, LiveBroadcast bean, Sort sort) {
        Limitable limit = RowSide.limitable(1, sort);
        List<LiveBroadcast> list = dao.findAll(spec(siteId, params), limit);
        return RowSide.create(list, bean);
    }

    private Specification<LiveBroadcast> spec(final Integer siteId, Map<String, String[]> params) {
        Collection<SearchFilter> filters = SearchFilter.parse(params).values();
        final Specification<LiveBroadcast> fsp = SearchFilter.spec(filters, LiveBroadcast.class);
        Specification<LiveBroadcast> sp = new Specification<LiveBroadcast>() {
            public Predicate toPredicate(Root<LiveBroadcast> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate pred = fsp.toPredicate(root, query, cb);
                if (siteId != null) {
                    pred = cb.and(pred, cb.equal(root.get("site")
                            .<Integer>get("id"), siteId));
                }
                return pred;
            }
        };
        return sp;
    }

    public LiveBroadcast get(Integer id) {
        return dao.findOne(id);
    }

    @Transactional
    public LiveBroadcast save(LiveBroadcast bean, Integer siteId) {
        Site site = siteService.get(siteId);
        bean.setSite(site);
        bean = dao.save(bean);
//        liveBroadcastService.save(bean,siteId);
        return bean;
    }

    @Transactional
    public LiveBroadcast update(LiveBroadcast bean, Integer[] id, String[] title) {
        bean = dao.save(bean);
//        liveBroadcastService.update(bean,id,title);
        return bean;
    }


    public LiveBroadcast delete(Integer id) {
        LiveBroadcast entity = dao.findOne(id);
        if (entity != null) {
            dao.delete(entity);
        }
        return entity;
    }


    public LiveBroadcast[] delete(Integer[] ids) {
        LiveBroadcast[] beans = new LiveBroadcast[ids.length];
        for (int i = 0; i < ids.length; i++) {
            beans[i] = delete(ids[i]);
        }
        return beans;
    }

    @Autowired
    private LiveBroadcastAddressService broadcastAddressService;

    @Autowired
    private SiteService siteService;

    @Autowired
    private LiveBroadcastDao dao;
}
